﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Develore.GDiff;
using System.IO;

namespace GDiffLibTests
{
	[TestClass]
	public class AdlerTests
	{

		#region Test: public void CreateAdler01()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		public void CreateAdler01()
		{
			byte[] buffer = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
			Adler32 hash = new Adler32(buffer);
			Assert.IsTrue(hash.Value > 1);
		}

		#endregion

		#region Test: public void CreateAdler02()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		public void CreateAdler02()
		{
			byte[] buffer1 = new byte[] { 87, 105, 107, 105, 112, 101, 100, 105, 97 };
			byte[] buffer2 = new byte[] { 1, 2, 3, 4, 5, 87, 105, 107, 105, 112, 101, 100, 105, 97 };

			Adler32 hash1 = new Adler32(buffer1);
			Adler32 hash2 = new Adler32(buffer2, 0, buffer1.Length);

			for (int i = 0; i < buffer2.Length - buffer1.Length; i++)
			{
				hash2.ComputeNext(buffer2[i], buffer2[buffer1.Length + i]);
			}

			Assert.AreEqual<Adler32>(hash1, hash2);
		}

		#endregion

		#region Test: public void CreateAdler03()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		public void CreateAdler03()
		{
			Adler32 hash = new Adler32(new byte[] { 0 });
			Assert.AreEqual<uint>(65537, hash.Value);
		}

		#endregion

		#region Test: public void CreateAdler04()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		public void CreateAdler04()
		{
			Adler32 hash = new Adler32(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
			string expected = hash.Value.ToString("X").PadLeft(8, '0');
			string actual = hash.ToString().Replace("-", string.Empty);

			Assert.AreEqual<string>(expected, actual);
		}

		#endregion

		#region Test: public void CreateAdler05()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		public void CreateAdler05()
		{

			byte[] buffer = new byte[4096];
			Random rnd = new Random();
			rnd.NextBytes(buffer);

			Adler32 hash = new Adler32(buffer);
			Assert.AreNotEqual<uint>(0, hash.Value);
		}

		#endregion

		#region Test: public void CreateAdler06()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		public void CreateAdler06()
		{
			byte[] buffer1 = new byte[] { 1, 2, 3, 4, 5, 6 };
			byte[] buffer2 = new byte[] { 2, 3, 4, 5 };
			byte[] buffer3 = new byte[] { 3, 4, 5, 6 };

			Adler32 hash1 = new Adler32(buffer1, 0, buffer3.Length);
			Adler32 hash2 = new Adler32(buffer2);
			Adler32 hash3 = new Adler32(buffer3);

			Assert.AreNotEqual<Adler32>(hash2, hash1);
			Assert.AreNotEqual<Adler32>(hash3, hash1);

			hash1.ComputeNext(buffer1[0], buffer1[4]);
			Assert.AreEqual<Adler32>(hash2, hash1);
			Assert.AreNotEqual<Adler32>(hash3, hash1);

			hash1.ComputeNext(buffer1[1], buffer1[5]);
			Assert.AreEqual<Adler32>(hash3, hash1);
			Assert.AreNotEqual<Adler32>(hash2, hash1);
		}

		#endregion

		#region Test: public void CreateAdler07()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		public void CreateAdler07()
		{
			byte[] buffer = new byte[255];
			new Random().NextBytes(buffer);

			Adler32 hash = new Adler32(buffer);
			string s = hash.ToString();

			Converter<string, byte[]> bufferConverter = delegate(string str)
			{
				string[] arr = str.Split('-');
				byte[] buf = new byte[arr.Length];

				for (int i = 0; i < arr.Length; i++)
				{
					buf[i] = byte.Parse(arr[i], System.Globalization.NumberStyles.HexNumber);
				}

				if (BitConverter.IsLittleEndian)
					buf = buf.Reverse().ToArray();

				return buf;
			};

			uint expected = BitConverter.ToUInt32(bufferConverter.Invoke(s), 0);
			Assert.AreEqual<uint>(expected, hash.Value);
		}

		#endregion

		#region Test: public void CreateAdler08()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute("This test case is taken from Wikipedia at http://en.wikipedia.org/wiki/Adler-32.")]
		public void CreateAdler08()
		{
			byte[] buffer = new byte[] { 87, 105, 107, 105, 112, 101, 100, 105, 97 };
			Adler32 hash = new Adler32(buffer);
			Assert.AreEqual<uint>(300286872, hash.Value);
		}

		#endregion

		#region Test: public void CreateAdler09()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute("This is a slight modification of the test case from Wikipedia at http://en.wikipedia.org/wiki/Adler-32.")]
		public void CreateAdler09()
		{
			byte[] buffer = new byte[] { 64, 87, 105, 107, 105, 112, 101, 100, 105, 97 };
			Adler32 hash = new Adler32(buffer, 0, buffer.Length - 1);

			hash.ComputeNext(buffer.First(), buffer.Last());
			Assert.AreEqual<uint>(300286872, hash.Value);
		}

		#endregion

		#region Test: public void CreateAdler10()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute("This test case is a slight modification of the example in Wikipedia at http://en.wikipedia.org/wiki/Adler-32.")]
		public void CreateAdler10()
		{
			byte[] buffer = new byte[] { 100, 87, 105, 107, 105, 112, 101, 100, 105, 97 };
			Adler32 hash = new Adler32(buffer, 0, buffer.Length - 1);
			hash.ComputeNext(buffer.First(), buffer.Last());

			PrivateObject po = new PrivateObject(hash);
			int A = (int)po.GetField("A");
			int B = (int)po.GetField("B");

			Assert.AreEqual<int>(920, A);
			Assert.AreEqual<int>(4582, B);
		}

		#endregion

		#region Test: public void CreateAdler11()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		public void CreateAdler11()
		{
			byte[] buffer1 = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
			byte[] buffer2 = new byte[] { 2, 3, 4, 5, 6, 7, 8, 9, 0 };

			Adler32 hash1 = new Adler32(buffer1, 1, buffer2.Length);
			Adler32 hash2 = new Adler32(buffer2);

			Assert.AreEqual<uint>(hash2.Value, hash1.Value);
		}

		#endregion

		#region Test: public void CreateAdler12()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		public void CreateAdler12()
		{
			Adler32 hash = new Adler32();
			Assert.AreEqual<int>(32, hash.HashSize);
		}

		#endregion

		#region Test: public void CreateAdler13()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		public void CreateAdler13()
		{
			Adler32 hash = new Adler32(new byte[] { 1, 2, 3, 4, 5 });
			Assert.AreEqual<int>(32, hash.HashSize);
		}

		#endregion

		#region Test: public void CreateAdler14()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		public void CreateAdler14()
		{
			Adler32 hash = new Adler32(new byte[] { 1, 2, 3, 4 }, 0, 4);
			Assert.AreEqual<int>(32, hash.HashSize);
		}

		#endregion
		


		#region Test: public void Hash01()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		public void Hash01()
		{
			Adler32 hash = new Adler32();
			byte[] buffer = new byte[] { 87, 105, 107, 105, 112, 101, 100, 105, 97 };
			hash.ComputeHash(buffer);

			string s = BitConverter.ToString(hash.Hash);
			Assert.AreEqual<string>("11-E6-03-98", s);
		}

		#endregion

		#region Test: public void Hash02()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		public void Hash02()
		{
			byte[] buffer = new byte[] { 87, 105, 107, 105, 112, 101, 100, 105, 97 };
			Adler32 hash = new Adler32();
			hash.ComputeHash(buffer);
			hash.ComputeNext(0, 0);

			Assert.AreEqual<string>("15-7D-03-98", hash.ToString());
		}

		#endregion

		#region Test: public void Hash03()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		public void Hash03()
		{
			using (Adler32 adler1 = new Adler32())
			{
				adler1.ComputeHash(new byte[] { 1, 2, 3 });
				adler1.ComputeNext(1, 4);
				adler1.ComputeNext(2, 5);
				adler1.ComputeNext(3, 6);

				using (Adler32 adler2 = new Adler32(new byte[] { 4, 5, 6 }))
				{
					Assert.AreEqual<Adler32>(adler2, adler1);
				}
			}
		}

		#endregion

		#region Test: public void Hash04()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		public void Hash04()
		{
			using (Adler32 adler1 = new Adler32(new byte[] { 1, 2, 3 }))
			{
				adler1.ComputeNext(1, 4);
				adler1.ComputeNext(2, 5);
				adler1.ComputeNext(3, 6);

				using (Adler32 adler2 = new Adler32(new byte[] { 4, 5, 6 }))
				{
					Assert.AreEqual<Adler32>(adler2, adler1);
				}
			}
		}

		#endregion

		#region Test: public void Hash05()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		public void Hash05()
		{
			using (Adler32 adler1 = new Adler32())
			{
				adler1.ComputeHash(new byte[] { 1, 2, 3 });

				using (Adler32 adler2 = new Adler32(new byte[] { 1, 2, 3 }))
				{
					adler1.ComputeNext(1, 4);
					adler2.ComputeNext(1, 4);

					Assert.AreEqual<Adler32>(adler1, adler2);
				}
			}
		}

		#endregion

		#region Test: public void Hash06()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		public void Hash06()
		{
			using (Adler32 a1 = new Adler32(new byte[] { 1, 2, 3 }))
			{
				using (Adler32 a2 = new Adler32())
				{
					a2.ComputeHash(new byte[] { 1, 2, 3 });
					Assert.AreEqual<Adler32>(a1, a2);
				}
			}
		}

		#endregion

		#region Test: public void Hash07()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		public void Hash07()
		{
			byte[] buffer = new byte[] { 87, 105, 107, 105, 112, 101, 100, 105, 97 };
			Adler32 adler = new Adler32(buffer);

			PrivateObject po = new PrivateObject(adler);
			int A = (int)po.GetField("A");
			int B = (int)po.GetField("B");

			Assert.AreEqual<int>(920, A);
			Assert.AreEqual<int>(4582, B);
		}

		#endregion

		#region Test: public void Hash08()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		public void Hash08()
		{
			byte[] buffer = new byte[] { 100, 87, 105, 107, 105, 112, 101, 100, 105, 97, 101 };
			using (Adler32 adler1 = new Adler32(buffer, 1, buffer.Length - 2))
			{
				using (Adler32 adler2 = new Adler32())
				{
					adler2.ComputeHash(buffer, 1, buffer.Length - 2);

					Assert.AreEqual<uint>(300286872, adler1.Value);
					Assert.AreEqual<Adler32>(adler1, adler2);
				}
			}
		}

		#endregion

		#region Test: public void Hash09()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		public void Hash09()
		{
			int blockSize = 512;
			byte[] buffer = new byte[blockSize];
			Buffer.BlockCopy(Properties.Resources.Word01a, 0, buffer, 0, blockSize);
			List<byte> bytes = new List<byte>(buffer);

			using (Adler32 adler1 = new Adler32(buffer))
			{
				using (Adler32 adler2 = new Adler32())
				{
					for (int i = blockSize; i < Properties.Resources.Word01a.Length; i++)
					{
						bytes.Add(Properties.Resources.Word01a[i]);

						adler1.ComputeNext(bytes.First(), bytes.Last());
						bytes.RemoveAt(0);

						adler2.ComputeHash(bytes.ToArray());

						Assert.AreEqual<Adler32>(adler2, adler1, "Hashes must equal at index: {0}", i - blockSize + 1);
					}
				}
			}
		}

		#endregion
		
	}
}
